home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / ted5.zip / IGRABSRC.ZIP / DOGRAB.BAK < prev    next >
Text File  |  1993-02-04  |  25KB  |  1,052 lines

  1. ////////////////////////////////////////////////////////////
  2. ////////////////////////////////////////////////////////////
  3. //
  4. // GRABBING ROUTINES
  5. //
  6. ////////////////////////////////////////////////////////////
  7. ////////////////////////////////////////////////////////////
  8. #include "igrab.h"
  9. #pragma hdrstop
  10.  
  11. ////////////////////////////////////////////////////////////
  12. //
  13. // FONTS - need VGA still
  14. //
  15. // FONT/M format:
  16. // unsigned numchars       - 2 bytes
  17. // unsigned charoffs[256]  - 512 bytes
  18. // char charwidths[256]    - 256 bytes
  19. // data  - masked: mask first, then data
  20. //       - nomask: data
  21. //
  22. // EGA note: plane 0-3, linear storage
  23. //
  24. ////////////////////////////////////////////////////////////
  25. int charoff[256];
  26. char cwidths[256];
  27.  
  28. void GrabFont(grabtype type)
  29. {
  30.  int grabamt,loop3,loop2,loop1,loop,fheight,fascii,x,y;
  31.  char *str1,*str,*comp=", ",*comp1="0123456789",name[20];
  32.  
  33.  
  34.  for (loop=0;loop<256;loop++)
  35.    cwidths[loop]=charoff[loop]=0;
  36.  
  37.  str=string+5;
  38.  
  39.  grabamt=atoi(str);
  40.  str=strpbrk(str,comp);
  41.  str=strpbrk(str,comp1);
  42.  fheight=atoi(str);
  43.  str=strpbrk(str,comp);
  44.  str=strpbrk(str,comp1);
  45.  fascii=atoi(str);
  46.  
  47.  if (!fheight)
  48.    errout("ERROR!: You didn't define the height of your font!\n"
  49.       "Your scriptfile needs to say 'GRAB <amt>,<height>,<asciistart>'");
  50.  
  51.  if (fascii+grabamt>256)
  52.    {
  53.     settext();
  54.     printf("ERROR! You can't grab more than 256 chars in a FONT!  You're starting\n");
  55.     printf("       at ASCII %d and grabbing %d chars! TOO MUCH!\n",fascii,grabamt);
  56.     nosound();
  57.     exit(1);
  58.    }
  59.  
  60.  x=y=16;
  61.  offset=0x302;
  62.  
  63.  //
  64.  // Info:
  65.  // * Fonts always start at 2,2 on the screen (grid coords)
  66.  //
  67.  
  68.  globalx=globaly=0;
  69.  for (loop1=fascii;loop1<fascii+grabamt;loop1++)
  70.    {
  71.     int found;
  72.     //
  73.     // first, find width of character OR next char
  74.     //
  75.     found=0;
  76.  
  77.     while(!found)
  78.       {
  79.        for (loop=x+1;loop<320;loop++)
  80.      if (CharEdgeCheck(loop,y+fheight))
  81.        {
  82.         cwidths[loop1]=loop-x;
  83.         found++;
  84.         break;
  85.        }
  86.  
  87.        //
  88.        // if we reached the right edge of the screen
  89.        // without finding a character, reset the xcoord
  90.        // to search the next row!
  91.        //
  92.        if (!found)
  93.      {
  94.       x=16;
  95.       //
  96.       // next row. if we're off the bottom of the
  97.       // screen, give an error!
  98.       //
  99.       y=(y+fheight+7)&0xf8;
  100.       if (y>200)
  101.         {
  102.          settext();
  103.          printf("ERROR!  You specified %d FONT CHARS to grab, but I could\n",grabamt);
  104.          printf("        only find %d!\n",loop1-fascii);
  105.          nosound();
  106.          exit(1);
  107.         }
  108.      }
  109.       }
  110.  
  111.     //
  112.     // store offset to this character in the table
  113.     //
  114.     charoff[loop1]=offset;
  115.  
  116.     //
  117.     // Grab mask first if we're grabbing a FONTM
  118.     //
  119.     if (type==FONTMTYPE)
  120.       {
  121.        switch(format[0])
  122.      {
  123.       case 'C':
  124.         for (loop2=y;loop2<y+fheight;loop2++)
  125.           for (loop3=x/4;loop3<x/4+(cwidths[loop1]+3)/4;loop3++)
  126.         *(databuffer+offset++)=(*(maskscreen+loop2*(CurrentLBM.width/4)+loop3))^0xff;
  127.         break;
  128.  
  129.       //
  130.       // next, grab mask in maskscreen, plane 0 and xor-0xff it
  131.       //
  132.       case 'E':
  133.         for (loop2=y;loop2<y+fheight;loop2++)
  134.           for (loop3=x/8;loop3<x/8+(cwidths[loop1]+7)/8;loop3++)
  135.         *(databuffer+offset++)=(*(maskscreen+loop2*(CurrentLBM.width/8)+loop3))^0xff;
  136.         break;
  137.       case 'V':
  138.         for (loop2=y;loop2<y+fheight;loop2++)
  139.           for (loop3=x;loop3<x+cwidths[loop1];loop3++)
  140.         *(databuffer+offset++)=(*(maskscreen+loop2*CurrentLBM.width+loop3))^0xff;
  141.      }
  142.        CheckBuffer();
  143.       }
  144.  
  145.     //
  146.     // Now, grab character data
  147.     //
  148.     switch(format[0])
  149.       {
  150.        case 'C':
  151.      for (loop2=y;loop2<y+fheight;loop2++)
  152.        for (loop3=x/4;loop3<x/4+(cwidths[loop1]+3)/4;loop3++)
  153.          *(databuffer+offset++)=*(lbmscreen+loop2*(CurrentLBM.width/4)+loop3);
  154.      x=(x+cwidths[loop1]+7)&0xfff8;
  155.      break;
  156.  
  157.        //
  158.        // next, grab char data in lbmscreen, plane 0
  159.        //
  160.        case 'E':
  161.      for (loop2=y;loop2<y+fheight;loop2++)
  162.        for (loop3=x/8;loop3<x/8+(cwidths[loop1]+7)/8;loop3++)
  163.          *(databuffer+offset++)=*(lbmscreen+loop2*(CurrentLBM.width/8)+loop3);
  164.      x=(x+cwidths[loop1]+7)&0xfff8;
  165.      break;
  166.        case 'V':
  167.      for (loop2=y;loop2<y+fheight;loop2++)
  168.        for (loop3=x;loop3<x+cwidths[loop1];loop3++)
  169.          *(databuffer+offset++)=*(lbmscreen+loop2*CurrentLBM.width+loop3);
  170.      x=(x+cwidths[loop1]+7)&0xfff8;
  171.       }
  172.  
  173.     //
  174.     // Time to BLIT the data to the screen!
  175.     //
  176.     if (!noshow && !SkipToStart)
  177.       switch(format[0])
  178.     {
  179.      //
  180.      // CGA
  181.      //
  182.      case 'C':
  183.        if (type==FONTMTYPE)
  184.          {
  185.           unsigned loop4,datoff,charsize=fheight*((cwidths[loop1]+3)/4),tmp;
  186.           unsigned char c,huge *CGAscrn=MK_FP(0xb800,0);
  187.  
  188.           datoff=charoff[loop1];
  189.  
  190.           for (loop2=0;loop2<fheight;loop2++)
  191.         for (loop3=0;loop3<(cwidths[loop1]+3)/4;loop3++)
  192.           {
  193.            tmp=globaly+loop2;
  194.            c=*(CGAscrn+0x2000*(tmp&1)+(tmp/2)*(CurrentLBM.width/4)+globalx+loop3);
  195.            c=(c)&(*(databuffer+datoff)^0xff)|(*(databuffer+charsize+datoff++));
  196.            *(CGAscrn+0x2000*(tmp&1)+(tmp/2)*(CurrentLBM.width/4)+globalx+loop3)=c;
  197.           }
  198.          }
  199.        else
  200.          {
  201.           unsigned loop4,datoff,tmp;
  202.           unsigned char c,huge *CGAscrn=MK_FP(0xb800,0);
  203.  
  204.           datoff=charoff[loop1];
  205.  
  206.           for (loop2=0;loop2<fheight;loop2++)
  207.         for (loop3=0;loop3<(cwidths[loop1]+3)/4;loop3++)
  208.           {
  209.            tmp=globaly+loop2;
  210.            c=*(CGAscrn+0x2000*(tmp&1)+(tmp/2)*(CurrentLBM.width/4)+globalx+loop3);
  211.            c=(c)|(*(databuffer+datoff++));
  212.            *(CGAscrn+0x2000*(tmp&1)+(tmp/2)*(CurrentLBM.width/4)+globalx+loop3)=c;
  213.           }
  214.          }
  215.  
  216.        globalx+=(cwidths[loop1]+3)/4;
  217.        if (globalx>78)
  218.          {
  219.           globalx=0;
  220.           globaly+=fheight;
  221.           if (globaly>200-fheight)
  222.         globaly=0;
  223.          }
  224.        break;
  225.      //
  226.      // EGA
  227.      //
  228.      case 'E':
  229.        if (type==FONTMTYPE)
  230.          {
  231.           unsigned loop4,datoff,charsize=fheight*((cwidths[loop1]+7)/8);
  232.           unsigned char c,huge *EGAscrn=MK_FP(0xa000,0);
  233.  
  234.           outport(GCindex,GCmode);
  235.           for (loop4=0;loop4<4;loop4++)
  236.         {
  237.          outport(GCindex,GCreadmap | (loop4*256));
  238.          outport(SCindex,SCmapmask | (1<<loop4)*256);
  239.          datoff=charoff[loop1];
  240.  
  241.          for (loop2=0;loop2<fheight;loop2++)
  242.            for (loop3=0;loop3<(cwidths[loop1]+7)/8;loop3++)
  243.              {
  244.               c=*(EGAscrn+(globaly+loop2)*(CurrentLBM.width/8)+globalx+loop3);
  245.               c=(c)&(*(databuffer+datoff)^0xff)|(*(databuffer+charsize+datoff++));
  246.               *(EGAscrn+(globaly+loop2)*(CurrentLBM.width/8)+globalx+loop3)=c;
  247.              }
  248.          }
  249.          }
  250.        else
  251.          {
  252.           unsigned loop4,datoff;
  253.           unsigned char c,huge *EGAscrn=MK_FP(0xa000,0);
  254.  
  255.           outport(GCindex,GCmode);
  256.           for (loop4=0;loop4<4;loop4++)
  257.         {
  258.          outport(GCindex,GCreadmap | (loop4*256));
  259.          outport(SCindex,SCmapmask | (1<<loop4)*256);
  260.          datoff=charoff[loop1];
  261.  
  262.          for (loop2=0;loop2<fheight;loop2++)
  263.            for (loop3=0;loop3<(cwidths[loop1]+7)/8;loop3++)
  264.              {
  265.               c=*(EGAscrn+(globaly+loop2)*(CurrentLBM.width/8)+globalx+loop3);
  266.               c=(c)|(*(databuffer+datoff++));
  267.               *(EGAscrn+(globaly+loop2)*(CurrentLBM.width/8)+globalx+loop3)=c;
  268.              }
  269.          }
  270.          }
  271.  
  272.        globalx+=(cwidths[loop1]+7)/8;
  273.        if (globalx>38)
  274.          {
  275.           globalx=0;
  276.           globaly+=fheight;
  277.           if (globaly>200-fheight)
  278.         globaly=0;
  279.          }
  280.        break;
  281.      //
  282.      // VGA
  283.      //
  284.      case 'V':
  285.        if (type==FONTMTYPE)
  286.          {
  287.           unsigned loop4,datoff,charsize=fheight*cwidths[loop1];
  288.           unsigned char c,huge *VGAscrn=MK_FP(0xa000,0);
  289.  
  290.           datoff=charoff[loop1];
  291.  
  292.           for (loop2=0;loop2<fheight;loop2++)
  293.         for (loop3=0;loop3<cwidths[loop1];loop3++)
  294.           {
  295.            c=*(VGAscrn+(globaly+loop2)*CurrentLBM.width+globalx+loop3);
  296.            c=(c)&(*(databuffer+datoff)^0xff)|(*(databuffer+charsize+datoff++));
  297.            *(VGAscrn+(globaly+loop2)*CurrentLBM.width+globalx+loop3)=c;
  298.           }
  299.          }
  300.        else
  301.          {
  302.           unsigned loop4,datoff;
  303.           unsigned char c,huge *VGAscrn=MK_FP(0xa000,0);
  304.  
  305.           datoff=charoff[loop1];
  306.  
  307.           for (loop2=0;loop2<fheight;loop2++)
  308.         for (loop3=0;loop3<cwidths[loop1];loop3++)
  309.           {
  310.            c=*(VGAscrn+(globaly+loop2)*CurrentLBM.width+globalx+loop3);
  311.            c=(c)|(*(databuffer+datoff++));
  312.            *(VGAscrn+(globaly+loop2)*CurrentLBM.width+globalx+loop3)=c;
  313.           }
  314.          }
  315.  
  316.        globalx+=cwidths[loop1];
  317.        if (globalx>304)
  318.          {
  319.           globalx=0;
  320.           globaly+=fheight;
  321.           if (globaly>200-fheight)
  322.         globaly=0;
  323.          }
  324.     }
  325.  
  326.     CheckBuffer();
  327.    }
  328.  
  329.  //
  330.  // move the completed arrays into the start of the font area
  331.  //
  332.  movedata(FP_SEG(charoff),FP_OFF(charoff),
  333.       FP_SEG(databuffer+2),FP_OFF(databuffer+2),512);
  334.  movedata(FP_SEG(cwidths),FP_OFF(cwidths),
  335.       FP_SEG(databuffer+514),FP_OFF(databuffer+514),256);
  336.  *(int huge *)databuffer=fheight;
  337.  
  338.  //
  339.  // save file out
  340.  //
  341.  CountBytes(databuffer,offset);
  342.  
  343.  switch(type)
  344.    {
  345.     case FONTTYPE:
  346.       FontOffs[Data[FONT].num]=Data[FONT].offset;
  347.       FontOffs[Data[FONT].num+1]=Data[FONT].offset+offset;
  348.       Data[FONT].offset+=offset;
  349.       Data[FONT].num++;
  350.       AddDataToFile("FONT");
  351.       break;
  352.     case FONTMTYPE:
  353.       FontMOffs[Data[FONTM].num]=Data[FONTM].offset;
  354.       FontMOffs[Data[FONTM].num+1]=Data[FONTM].offset+offset;
  355.       Data[FONTM].offset+=offset;
  356.       Data[FONTM].num++;
  357.       AddDataToFile("FONTM");
  358.    }
  359. }
  360.  
  361. ////////////////////////////////////////////////////////////
  362. //
  363. // Find the right edge of a character.
  364. // Pass pixel coords, please.
  365. //
  366. char CharEdgeCheck(int x,int y)
  367. {
  368.  char value;
  369.  
  370.  switch(format[0])
  371.  {
  372.   case 'C':
  373.     value=(lbmscreen[y*(CurrentLBM.width/4)+x/4]>>(6-2*(x%4)))&3;
  374.     break;
  375.   case 'E':
  376.     value=(lbmscreen[y*(CurrentLBM.width/8)+x/8]>>(7-(x%8)))&1;
  377.     break;
  378.   case 'V':
  379.     value=lbmscreen[y*CurrentLBM.width+x];
  380.  }
  381.  
  382.  return value;
  383. }
  384.  
  385.  
  386.  
  387. ////////////////////////////////////////////////////////////
  388. //
  389. // Grab info from the screen for any graphics mode
  390. // NON-MASKED
  391. //
  392. ////////////////////////////////////////////////////////////
  393. void DoGrab(int x,int y,int width,int height,unsigned offset)
  394. {
  395.  switch(format[0])
  396.    {
  397.     case 'C': CGAgrab(x/4,y,width/4,height,offset); break;
  398.     case 'E': EGAgrab(x/8,y,width/8,height,offset); break;
  399.     case 'V': VGAgrab(x,y,width,height,offset); break;
  400.    }
  401. }
  402.  
  403.  
  404.  
  405. ////////////////////////////////////////////////////////////
  406. //
  407. // Grab info from the screen for any graphics mode
  408. // MASKED
  409. //
  410. ////////////////////////////////////////////////////////////
  411. void DoMGrab(int x,int y,int width,int height,unsigned offset,int opt)
  412. {
  413.  switch(format[0])
  414.    {
  415.     case 'C': CGAMgrab(x/4,y,width/4,height,offset,opt); break;
  416.     case 'E': EGAMgrab(x/8,y,width/8,height,offset,opt); break;
  417.     case 'V': VGAMgrab(x,y,width,height,offset,opt);
  418.    }
  419. }
  420.  
  421.  
  422.  
  423. ////////////////////////////////////////////////////////////
  424. //
  425. // Blit info to the screen for any graphics mode
  426. // MASKED
  427. //
  428. ////////////////////////////////////////////////////////////
  429. void DoMBlit(int x,int y,int width,int height,int yadd,int hadd)
  430. {
  431.  switch(format[0])
  432.    {
  433.     case 'C': DoCGAMblit(x/4,y,width/4,height,yadd,hadd); break;
  434.     case 'E': DoEGAMblit(x/8,y,width/8,height,yadd,hadd); break;
  435.     case 'V': DoVGAMblit(x,y,width,height,yadd,hadd);
  436.    }
  437. }
  438.  
  439.  
  440.  
  441. ////////////////////////////////////////////////////////////
  442. //
  443. // Blit info to the screen for any graphics mode
  444. // NON-MASKED
  445. //
  446. ////////////////////////////////////////////////////////////
  447. void DoBlit(int x,int y,int width,int height)
  448. {
  449.  switch(format[0])
  450.    {
  451.     case 'C': DoCGAblit(x/4,y,width/4,height); break;
  452.     case 'E': DoEGAblit(x/8,y,width/8,height); break;
  453.     case 'V': DoVGAblit(x,y,width,height);
  454.    }
  455. }
  456.  
  457.  
  458.  
  459. ////////////////////////////////////////////////////////////
  460. //
  461. // SparseTile checking, for any video mode
  462. // Exit: 1 = sparse tile, 0 = normal tile
  463. //
  464. ////////////////////////////////////////////////////////////
  465. int CheckSparse(int x,int y)
  466. {
  467.  int i,j;
  468.  long size;
  469.  unsigned char c;
  470.  
  471.  switch(format[0])
  472.    {
  473.     case 'C':
  474.       c=*(lbmscreen+y*(CurrentLBM.width/4)+x/4);
  475.       if (c!=0xff)
  476.     return 0;
  477.       for (j=y+1;j<y+8;j++)
  478.     {
  479.      c=*(lbmscreen+j*(CurrentLBM.width/4)+x/4);
  480.      if (c!=0xc0)
  481.        return 0;
  482.     }
  483.       break;
  484.  
  485.     case 'E':
  486.       size=(CurrentLBM.width/8)*CurrentLBM.height;
  487.       for (i=0;i<4;i++)
  488.     {
  489.      c=*(lbmscreen+size*i+y*(CurrentLBM.width/8)+x/8);
  490.      if (c!=0xff)
  491.        return 0;
  492.      for (j=y+1;j<y+8;j++)
  493.        {
  494.         c=*(lbmscreen+size*i+j*(CurrentLBM.width/8)+x/8);
  495.         if (c!=0x80)
  496.           return 0;
  497.        }
  498.     }
  499.       break;
  500.  
  501.     case 'V':
  502.       for (j=x;j<x+8;j++)
  503.     {
  504.      c=*(lbmscreen+(unsigned)y*CurrentLBM.width+j)&0xf;
  505.      if (c!=0xf)
  506.        return 0;
  507.     }
  508.  
  509.       for (j=y+1;j<y+8;j++)
  510.     {
  511.      c=*(lbmscreen+(unsigned)j*CurrentLBM.width+x)&0xf;
  512.      if (c!=0xf)
  513.        return 0;
  514.     }
  515.  
  516.    }
  517.  
  518.  return 1;
  519. }
  520.  
  521.  
  522.  
  523. ////////////////////////////////////////////////////////////
  524. //
  525. // HANDLE ANY TILE!
  526. // Currently supported sizes:
  527. // 8,16,32; masked & non-masked
  528. //
  529. ////////////////////////////////////////////////////////////
  530. void GrabTile(grabtype type)
  531. {
  532.  int xadd,yadd,hw,masked,fullscreen,newtype,althsize,gridhsize,
  533.      xmult,ymult,maxamount,amount,loop,fullwidth;
  534.  char typestr[8][10]={"FONT","FONTM","TILE8","TILE8M","TILE16",
  535.     "TILE16M","TILE32","TILE32M"};
  536.  
  537.  
  538.  switch(type)
  539.    {
  540.     case TILE8MTYPE:
  541.     case TILE8TYPE:
  542.       xadd=yadd=16;
  543.       maxamount=MAXGRID8;    // max amount per screen
  544.       ymult=xmult=16;        // x/y screen spacing for grab
  545.       althsize=ALT8H;        // horiz max per ALT line
  546.       gridhsize=GRID8H;        // horiz max per GRID line
  547.       newtype=TILE8;        // new indexing var
  548.       fullwidth=masked=0;    // masked data or not
  549.       if (type==TILE8MTYPE)
  550.     masked=newtype=TILE8M;
  551.       fullscreen=12*ALT8H;    // fullscreen for GRID8 type
  552.       hw=8;            // how many pixels to grab horiz & vert
  553.       break;
  554.  
  555.     case ALT8MTYPE:
  556.     case ALT8TYPE:
  557.       xadd=yadd=16;
  558.       maxamount=MAXALT8;
  559.       ymult=xmult=8;
  560.       althsize=ALT8H;
  561.       gridhsize=GRID8H;
  562.       newtype=TILE8;
  563.       masked=0;
  564.       fullwidth=1;
  565.       if (type==ALT8MTYPE)
  566.     masked=newtype=TILE8M;
  567.       fullscreen=maxamount;
  568.       hw=8;
  569.       break;
  570.  
  571.     case TILE16TYPE:
  572.     case TILE16MTYPE:
  573.       xadd=yadd=16;
  574.       maxamount=MAXGRID16;
  575.       ymult=xmult=24;
  576.       althsize=ALT16H;
  577.       gridhsize=GRID16H;
  578.       newtype=TILE16;
  579.       fullwidth=masked=0;
  580.       if (type==TILE16MTYPE)
  581.     masked=newtype=TILE16M;
  582.       fullscreen=8*ALT16H;
  583.       hw=16;
  584.       break;
  585.  
  586.     case ALT16TYPE:
  587.     case ALT16MTYPE:
  588.       xadd=24;
  589.       yadd=0;
  590.       maxamount=MAXALT16;
  591.       ymult=xmult=16;
  592.       althsize=ALT16H;
  593.       gridhsize=GRID16H;
  594.       newtype=TILE16;
  595.       masked=0;
  596.       fullwidth=1;
  597.       if (type==ALT16MTYPE)
  598.     masked=newtype=TILE16M;
  599.       fullscreen=maxamount;
  600.       hw=16;
  601.       break;
  602.  
  603.     case TILE32TYPE:
  604.     case TILE32MTYPE:
  605.       xadd=yadd=16;
  606.       maxamount=MAXGRID32;
  607.       ymult=xmult=40;
  608.       althsize=ALT32H;
  609.       gridhsize=GRID32H;
  610.       newtype=TILE32;
  611.       fullwidth=masked=0;
  612.       if (type==TILE32MTYPE)
  613.     masked=newtype=TILE32M;
  614.       fullscreen=4*ALT32H;
  615.       hw=32;
  616.       break;
  617.  
  618.     case ALT32TYPE:
  619.     case ALT32MTYPE:
  620.       xadd=24;
  621.       yadd=0;
  622.       maxamount=MAXALT32;
  623.       ymult=xmult=32;
  624.       althsize=ALT32H;
  625.       gridhsize=GRID32H;
  626.       newtype=TILE32;
  627.       masked=0;
  628.       fullwidth=1;
  629.       if (type==ALT32MTYPE)
  630.     masked=newtype=TILE32M;
  631.       fullscreen=maxamount;
  632.       hw=32;
  633.       break;
  634.    }
  635.  
  636.  amount=atoi(string+4);
  637.  if (amount>maxamount)
  638.    {
  639.     char msg[80]="ERROR: You can't grab more than ",temp[10];
  640.  
  641.     itoa(maxamount,temp,10);
  642.     strcat(msg,temp);
  643.     strcat(msg," TILE8s on a page!");
  644.     errout(msg);
  645.    }
  646.  
  647.  //
  648.  // if keyword was GRAB with no parms, grab entire screen!
  649.  //
  650.  if (!amount)
  651.    amount=fullscreen;
  652.  
  653.  //
  654.  // Make sure that there's an even multiple of "althsize" tiles per line
  655.  //
  656.  if (amount%althsize)
  657.    amount=((amount+althsize-1)/althsize)*althsize;
  658.  
  659.  for (loop=0;loop<amount;loop++)
  660.    {
  661.     int x,y,sparse;
  662.  
  663.     y=yadd+(loop/althsize)*ymult;
  664.     x=(loop%althsize)*xmult+xadd;
  665.  
  666.     sparse=0;
  667.     if (loop%althsize>=gridhsize && !fullwidth)
  668.       sparse=1;
  669.     else
  670.      {
  671.       if (CheckSparse(x,y))
  672.     sparse=1;
  673.       else
  674.        {
  675.     if (masked)
  676.       {
  677.        DoMGrab(x,y,hw,hw,offset,0);
  678.        if (bit)
  679.          {
  680.           if (setbit)
  681.         {
  682.          DoBlit(x,y,hw,hw);
  683.          switch(type)
  684.          {
  685.           case TILE8MTYPE:
  686.           case ALT8MTYPE:
  687.             if (!cmpt8)
  688.               break;
  689.  
  690.             offset+=Data[TILE8].graphlen[gmode];
  691.             break;
  692.           case TILE16MTYPE:
  693.           case ALT16MTYPE:
  694.             offset+=Data[TILE16].graphlen[gmode];
  695.             break;
  696.           case TILE32MTYPE:
  697.           case ALT32MTYPE:
  698.             offset+=Data[TILE32].graphlen[gmode];
  699.          }
  700.         }
  701.           else
  702.         {
  703.          DoMBlit(x,y,hw,hw,0,0);
  704.          offset+=Data[newtype].graphlen[gmode];
  705.         }
  706.  
  707.           //
  708.           // INC WHICHBIT
  709.           //
  710.           switch(type)
  711.           {
  712.            case TILE8MTYPE:
  713.            case ALT8MTYPE:
  714.          if (!cmpt8)
  715.            break;
  716.  
  717.          T8whichbit++;
  718.          break;
  719.            case TILE16MTYPE:
  720.            case ALT16MTYPE:
  721.          T16whichbit++;
  722.          break;
  723.            case TILE32MTYPE:
  724.            case ALT32MTYPE:
  725.          T32whichbit++;
  726.           }
  727.          }
  728.        else
  729.          {
  730.           DoMBlit(x,y,hw,hw,0,0);
  731.           offset+=Data[newtype].graphlen[gmode];
  732.          }
  733.       }
  734.     else
  735.       {
  736.        DoGrab(x,y,hw,hw,offset);
  737.        DoBlit(x,y,hw,hw);
  738.        //
  739.        // Munge VGA ModeX graphics?
  740.        //
  741.        if (ModeX)
  742.          VL_MungePic((unsigned char far *)databuffer,hw,hw);
  743.  
  744.        offset+=Data[newtype].graphlen[gmode];
  745.       }
  746.        }
  747.      }
  748.  
  749. //    if (!cmpt8 && sparse)
  750. //      errout("You can't have any SPARSE tiles if your\nTILE8s are grabbed in one clump!");
  751.  
  752.     if (bit && sparse)
  753.       //
  754.       // INC WHICHBIT
  755.       //
  756.       switch(type)
  757.       {
  758.        case TILE8MTYPE:
  759.        case ALT8MTYPE:
  760.      if (!cmpt8)
  761.        break;
  762.  
  763.      T8whichbit++;
  764.      break;
  765.        case TILE16MTYPE:
  766.        case ALT16MTYPE:
  767.      T16whichbit++;
  768.      break;
  769.        case TILE32MTYPE:
  770.        case ALT32MTYPE:
  771.      T32whichbit++;
  772.       }
  773.  
  774.     Sparse[newtype*totalobjects+loop+Data[newtype].num]=sparse;
  775.     CheckBuffer();
  776.    }
  777.  
  778.  CountBytes(databuffer,offset);
  779.  AddDataToFile(typestr[newtype]);
  780.  Data[newtype].num+=amount;
  781. }
  782.  
  783.  
  784.  
  785. ////////////////////////////////////////////////////////////
  786. //
  787. // PICS
  788. //
  789. ////////////////////////////////////////////////////////////
  790. void GrabPics(grabtype type)
  791. {
  792.  int strptr,loop,x,y,w,h;
  793.  char *str,*comp=", ",*comp1="0123456789",name[40],*comp2="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  794.  long size;
  795.  
  796.  
  797.  if (Data[PIC].num==PicAmount)
  798.    {
  799.     settext();
  800.     printf("ERROR: You have reached the limit of PICS that can be grabbed.\n");
  801.     printf("       A change to IGRAB is required -- contact John Romero!\n");
  802.     nosound();
  803.     exit(1);
  804.    }
  805.  
  806.  str=string+5;
  807.  
  808.  
  809.  str=strpbrk(str,comp1);
  810.  x=atoi(str);
  811.  str=strpbrk(str,comp);
  812.  str=strpbrk(str,comp1);
  813.  y=atoi(str)*8;
  814.  str=strpbrk(str,comp);
  815.  str=strpbrk(str,comp1);
  816.  w=atoi(str);
  817.  str=strpbrk(str,comp);
  818.  str=strpbrk(str,comp1);
  819.  h=atoi(str);
  820.  str=strpbrk(str,comp);
  821.  str=strpbrk(str,comp2);
  822.  memset(name,0,40);
  823.  strcpy(name,str);
  824.  for (i=0;i<strlen(name);i++)
  825.    if (name[i]=='\r')
  826.      name[i]=0;
  827.  
  828.  if (type==PICMTYPE)
  829.    {
  830.     switch(format[0])
  831.       {
  832.        case 'C': CGAMgrab(x*2,y,w*2,h*8,offset,0);
  833.          DoCGAMblit(x*2,y,w*2,h*8,0,0);
  834.          size=2L*((w*2)*(h*8));
  835.          offset+=size;
  836.          w*=2;
  837.          break;
  838.        case 'E': EGAMgrab(x,y,w,h*8,offset,0);
  839.          DoEGAMblit(x,y,w,h*8,0,0);
  840.          size=5L*(w*(h*8));
  841.          offset+=size;
  842.          break;
  843.        case 'V': VGAMgrab(x*8,y,w*8,h*8,offset,0);
  844.          DoVGAMblit(x*8,y,w*8,h*8,0,0);
  845.          size=16L*w*h;
  846.          offset+=size;
  847.          w*=8;
  848.       }
  849.     (PicmTable+Data[PICM].num)->width=w;
  850.     (PicmTable+Data[PICM].num)->height=h*8;
  851.     _fmemcpy((char far *)PicMNames+Data[PICM].num*NAMELEN,name,NAMELEN);
  852.     PicMOffs[Data[PICM].num]=Data[PICM].offset;
  853.     PicMOffs[Data[PICM].num+1]=Data[PICM].offset+size;
  854.     Data[PICM].offset+=size;
  855.     Data[PICM].num++;
  856.    }
  857.  else
  858.    {
  859.     switch(format[0])
  860.       {
  861.        case 'C': CGAgrab(x*2,y,w*2,h*8,offset);
  862.          DoCGAblit(x*2,y,w*2,h*8);
  863.          size=(w*2)*(h*8);
  864.          offset+=size;
  865.          w*=2;
  866.          break;
  867.        case 'E': EGAgrab(x,y,w,h*8,offset);
  868.          DoEGAblit(x,y,w,h*8);
  869.          size=(w*(h*8))*4L;
  870.          offset+=size;
  871.          break;
  872.        case 'V': VGAgrab(x*8,y,w*8,h*8,offset);
  873.          DoVGAblit(x*8,y,w*8,h*8);
  874.          size=64L*w*h;
  875.          offset+=size;
  876.          w*=8;
  877.       }
  878.     (PicTable+Data[PIC].num)->width=w;
  879.     (PicTable+Data[PIC].num)->height=h*8;
  880.     _fmemcpy((char far *)PicNames+Data[PIC].num*NAMELEN,(char far *)name,NAMELEN);
  881.     PicOffs[Data[PIC].num]=Data[PIC].offset;
  882.     PicOffs[Data[PIC].num+1]=Data[PIC].offset+size;
  883.     Data[PIC].offset+=size;
  884.     Data[PIC].num++;
  885.    }
  886.  
  887.  CheckBuffer();
  888. }
  889.  
  890.  
  891.  
  892. ////////////////////////////////////////////////////////////
  893. //
  894. // SPRITES
  895. //
  896. ////////////////////////////////////////////////////////////
  897. void GrabSprites(void)
  898. {
  899.  int oldh,ychng,strptr,loop,x,y,w,h,xl,yl,xh,yh;
  900.  char *str1,*str,*comp=", ",*comp1="-0123456789",name[40],*comp2="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  901.  long size;
  902.  
  903.  if (Data[SPRITE].num==MAXSPRITES)
  904.    {
  905.     settext();
  906.     printf("ERROR: You have reached the limit of SPRITES that can be grabbed.\n");
  907.     printf("       A change to IGRAB is required -- contact John Romero!\n");
  908.     nosound();
  909.     exit(1);
  910.    }
  911.  
  912.  SpriteTable[Data[SPRITE].num].orgx=0;
  913.  SpriteTable[Data[SPRITE].num].orgy=0;
  914.  SpriteTable[Data[SPRITE].num].shifts=shifts;
  915.  
  916.  str=string+5;
  917.  
  918.  str=strpbrk(str,comp1);
  919.  x=atoi(str);
  920.  str=strpbrk(str,comp);
  921.  str=strpbrk(str,comp1);
  922.  y=atoi(str)*8;
  923.  str=strpbrk(str,comp);
  924.  str=strpbrk(str,comp1);
  925.  w=atoi(str);
  926.  str=strpbrk(str,comp);
  927.  str=strpbrk(str,comp1);
  928.  h=atoi(str);
  929.  str=strpbrk(str,comp);
  930.  str=strpbrk(str,comp1);
  931.  xl=frac*atoi(str);
  932.  SpriteTable[Data[SPRITE].num].xl=xl;
  933.  str=strpbrk(str,comp);
  934.  str=strpbrk(str,comp1);
  935.  yl=frac*atoi(str);
  936.  SpriteTable[Data[SPRITE].num].yl=yl;
  937.  str=strpbrk(str,comp);
  938.  str=strpbrk(str,comp1);
  939.  xh=frac*(w*8-atoi(str)-1);
  940.  SpriteTable[Data[SPRITE].num].xh=xh;
  941.  str=strpbrk(str,comp);
  942.  str=strpbrk(str,comp1);
  943.  yh=frac*(h*8-atoi(str)-1);
  944.  SpriteTable[Data[SPRITE].num].yh=yh;
  945.  str=strpbrk(str,comp);
  946.  str=strpbrk(str,comp2);
  947.  memset(name,0,40);
  948.  str1=strpbrk(str,comp);    // scan past name
  949.  
  950.  if (str1!=NULL)
  951.    {
  952.     strcpy(name,str);
  953.     for (i=0;i<strlen(name);i++)
  954.       if (name[i]==',')
  955.     {
  956.      name[i]=0;
  957.      break;
  958.     }
  959.  
  960.     str1=strupr(str1);
  961.     for (i=0;i<strlen(str1);i++)
  962.       {
  963.        if (!strncmp(str1+i,"OX=",3))
  964.      {
  965.       int temp;
  966.  
  967.       temp=SpriteTable[Data[SPRITE].num].orgx=8*frac*atoi(str1+i+3);
  968.       SpriteTable[Data[SPRITE].num].xl+=temp;
  969.       SpriteTable[Data[SPRITE].num].xh+=temp;
  970.      }
  971.        else
  972.        if (!strncmp(str1+i,"OY=",3))
  973.      {
  974.       int temp;
  975.  
  976.       temp=SpriteTable[Data[SPRITE].num].orgy=8*frac*atoi(str1+i+3);
  977.       SpriteTable[Data[SPRITE].num].yl+=temp;
  978.       SpriteTable[Data[SPRITE].num].yh+=temp;
  979.      }
  980.        else
  981.        if (!strncmp(str1+i,"SHIFTS=",7))
  982.      SpriteTable[Data[SPRITE].num].shifts=atoi(str1+i+7);
  983.       }
  984.    }
  985.  else
  986.    {
  987.     strcpy(name,str);
  988.     for (i=0;i<strlen(name);i++)
  989.       if (name[i]=='\r')
  990.     name[i]=0;
  991.    }
  992.  
  993.  h*=8;
  994.  switch(format[0])
  995.    {
  996.     case 'C': SpriteTable[Data[SPRITE].num].shifts/=2;
  997.           CGAMgrab(x*2,y,w*2,h,offset,1);
  998.           oldh=h;
  999.           ychng=Optimum.y-y;
  1000.           if (Optimum.height)
  1001.         h=SpriteTable[Data[SPRITE].num].height=Optimum.height-ychng+1;
  1002.           if (Optimum.y)
  1003.         {
  1004.          SpriteTable[Data[SPRITE].num].orgy+=ychng*frac;
  1005.          y=Optimum.y;
  1006.         }
  1007.           DoCGAMblit(x*2,y,w*2,h,ychng,oldh-(h+ychng));
  1008.           size=2L*(w*2)*h;
  1009.           offset+=size;
  1010.           w*=2;
  1011.           break;
  1012.     case 'E': EGAMgrab(x,y,w,h,offset,1);
  1013.           oldh=h;
  1014.           ychng=Optimum.y-y;
  1015.           if (Optimum.height)
  1016.         h=SpriteTable[Data[SPRITE].num].height=Optimum.height-ychng+1;
  1017.           if (Optimum.y)
  1018.         {
  1019.          SpriteTable[Data[SPRITE].num].orgy+=ychng*frac;
  1020.          y=Optimum.y;
  1021.         }
  1022.           DoEGAMblit(x,y,w,h,ychng,oldh-(h+ychng));
  1023.           size=w*h*5L;
  1024.           offset+=size;
  1025.           break;
  1026.     case 'V': SpriteTable[Data[SPRITE].num].shifts=1;
  1027.           VGAMgrab(x*8,y,w*8,h,offset,1);
  1028.           oldh=h;
  1029.           ychng=Optimum.y-y;
  1030.           if (Optimum.height)
  1031.         h=SpriteTable[Data[SPRITE].num].height=Optimum.height-ychng+1;
  1032.           if (Optimum.y)
  1033.         {
  1034.          SpriteTable[Data[SPRITE].num].orgy+=ychng*frac;
  1035.          y=Optimum.y;
  1036.         }
  1037.           DoVGAMblit(x*8,y,w*8,h,ychng,oldh-(h+ychng));
  1038.           size=16L*w*h;
  1039.           offset+=size;
  1040.           w*=8;
  1041.    }
  1042.  
  1043.  SpriteTable[Data[SPRITE].num].width=w;
  1044.  SpriteTable[Data[SPRITE].num].height=h;
  1045.  _fmemcpy((char far *)SpriteNames+Data[SPRITE].num*NAMELEN,(char far *)name,NAMELEN);
  1046.  SpriteOffs[Data[SPRITE].num]=Data[SPRITE].offset;
  1047.  SpriteOffs[Data[SPRITE].num+1]=Data[SPRITE].offset+size;
  1048.  Data[SPRITE].offset+=size;
  1049.  Data[SPRITE].num++;
  1050.  CheckBuffer();
  1051. }
  1052.